﻿#region Copyright Notice
// This file is part of GestionPedago.
// <description>
// Copyright (C) 2012 ENI Ecole Informatique
// 
// GestionPedago is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// <program> is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using GestionPedago.EntityContext;
using GestionPedago.Services.Framework;
using GestionPedago.Services.ES.Modele;
using GestionPedago.EntityContext.EntityOPTools;
using GestionPedago.Persistence.OPManager;

namespace GestionPedago.Services.Mapping {
    /// <summary>
    /// Classe de mapping Entity<->ES de l'objet Appreciation
    /// </summary>
    public class ECFMappeur : IMappeur<ECF, ECFES> {
        private CompetenceParECFMappeur mapCompParECF = new CompetenceParECFMappeur();
        private CompetenceMappeur mapComp = new CompetenceMappeur();
        private ModuleParECFMappeur mapModParECF = new ModuleParECFMappeur();
        private ModuleMappeur mapMod = new ModuleMappeur();
        private VersionECFMappeur mapVersion = new VersionECFMappeur();

        /// <summary>
        /// Constructeur
        /// </summary>
        public ECFMappeur() { }

        /// <summary>
        /// Mapping Entity -> ES
        /// </summary>
        /// <param name="entity">L'entity � mapper</param>
        /// <returns>L'ES obtenu</returns>
        public ECFES Entity2ES(ECF entity) {
            ECFES retour = new ECFES();
            retour.IdECF = entity.IdECF;
            retour.Libelle = entity.Libelle;
            retour.ListeCompetenceParECF = new List<CompetenceParECFES>();
            retour.ListeCompetence = new List<CompetenceES>();
            retour.ListeModuleParECF = new List<ModuleParECFES>();
            retour.ListeModule = new List<ModuleES>();
            retour.ListeVersionECF = new List<VersionECFES>();
            retour.ListeCompetenceTextuelle = String.Empty;
            foreach(CompetenceParECF cpe in entity.CompetenceParECF) {
                retour.ListeCompetence.Add(mapComp.Entity2ES(cpe.Competence));
                retour.ListeCompetenceParECF.Add(mapCompParECF.Entity2ES(cpe));
                if(retour.ListeCompetenceTextuelle == string.Empty) {
                    retour.ListeCompetenceTextuelle += cpe.Competence.Libelle;
                } else {
                    retour.ListeCompetenceTextuelle += ", " + cpe.Competence.Libelle;
                }
            }
            retour.ListeModuleTextuelle = String.Empty;
            foreach(ModuleParECF mpe in entity.ModuleParECF) {
                retour.ListeModule.Add(mapMod.Entity2ES(mpe.Module));
                retour.ListeModuleParECF.Add(mapModParECF.Entity2ES(mpe));
                if(retour.ListeModuleTextuelle == string.Empty) {
                    retour.ListeModuleTextuelle += mpe.Module.LibelleCourt;
                } else {
                    retour.ListeModuleTextuelle += ", " + mpe.Module.LibelleCourt;
                }
            }
            retour.ListeVersionECFTextuelle = String.Empty;
            foreach(VersionECF v in entity.VersionECF) {
                retour.ListeVersionECF.Add(mapVersion.Entity2ES(v));
                if(retour.ListeVersionECFTextuelle == string.Empty) {
                    retour.ListeVersionECFTextuelle += v.Libelle;
                } else {
                    retour.ListeVersionECFTextuelle += ", " + v.Libelle;
                }
            }

            return retour;
        }

        /// <summary>
        /// Mapping ES -> Entity
        /// </summary>
        /// <param name="es">L'ES � mapper</param>
        /// <returns>L'entity obtenu</returns>
        public ECF ES2Entity(ECFES es) {

            ECF retour = new ECF();
            retour.IdECF = es.IdECF;
            bool alreadyAttached = !EntityStateChecker.IsDetached(retour);
            if(!alreadyAttached) {
                EntityConnection.GetContext().ECF.Attach(retour);
            }
            retour.Libelle = es.Libelle;

            // Suppression des Version
            List<VersionECF> lstVersionECFASupprimer = new List<VersionECF>();
            List<VersionECF> lstVersions = VersionECFOPManager.GetVersionECFByIdECF(es.IdECF);
            foreach(VersionECF v in lstVersions) {
                VersionECFES ve = mapVersion.Entity2ES(v);
                if(!es.ListeVersionECF.Contains(ve)) {
                    lstVersionECFASupprimer.Add(v);
                }
            }

            // Cr�ation des nouvelles entit�s
            foreach(VersionECFES ves in es.ListeVersionECF) {
                if(ves.IdVersionECF == 0) {
                    if(!String.IsNullOrWhiteSpace(ves.Libelle)) {
                        VersionECF v = new VersionECF();
                        v.IdECF = ves.IdECF;
                        v.Libelle = ves.Libelle;
                        if(retour.IdECF != 0) {
                            v.IdECF = retour.IdECF;
                            VersionECFOPManager.AjouterVersionECF(v);
                        } else {
                            retour.VersionECF.Add(v);
                        }
                    }
                } else {
                    VersionECF v = mapVersion.ES2Entity(ves);
                    // Si le libell� est vide on supprime la version
                    if(String.IsNullOrWhiteSpace(ves.Libelle)) {
                        lstVersionECFASupprimer.Add(v);
                    }
                }

            }

            // Suppression effective
            foreach(VersionECF v in lstVersionECFASupprimer) {
                //retour.VersionECF.Remove(v);
                VersionECFOPManager.SupprimerVersionECF(v);
            }

            foreach(CompetenceES ce in es.ListeCompetence) {
                CompetenceParECFES cpee = new CompetenceParECFES();
                cpee.IdECF = es.IdECF;
                cpee.IdCompetence = ce.IdCompetence;
                if(!es.ListeCompetenceParECF.Contains(cpee)) {
                    es.ListeCompetenceParECF.Add(cpee);
                    if(retour.IdECF > 0) {
                        CompetenceParECF cpe = CompetenceParECFOPManager.AjouterCompetenceParECF(mapCompParECF.ES2Entity(cpee));
                    } /*else {
                        retour.CompetenceParECF.Add(mapCompParECF.ES2Entity(cpee));
                    }*/
                }
            }

            List<CompetenceParECFES> lstCompetencesARetirer = new List<CompetenceParECFES>();
            foreach(CompetenceParECFES cpee in es.ListeCompetenceParECF) {
                CompetenceES ce = new CompetenceES();
                ce.IdCompetence = cpee.IdCompetence;
                if(!es.ListeCompetence.Contains(ce)) {
                    lstCompetencesARetirer.Add(cpee);
                }
            }

            foreach(CompetenceParECFES cpee in lstCompetencesARetirer) {
                es.ListeCompetenceParECF.Remove(cpee);
                CompetenceParECFOPManager.SupprimerCompetenceParECF(CompetenceParECFOPManager.GetCompetenceParECFByIdCompetenceIdECF(cpee.IdCompetence, cpee.IdECF));
            }

            foreach(ModuleES me in es.ListeModule) {
                ModuleParECFES mpee = new ModuleParECFES();
                mpee.IdECF = es.IdECF;
                mpee.IdModule = me.IdModule;
                if(!es.ListeModuleParECF.Contains(mpee)) {
                    es.ListeModuleParECF.Add(mpee);
                    if(retour.IdECF > 0) {
                        ModuleParECF mpe = ModuleParECFOPManager.AjouterModuleParECF(mapModParECF.ES2Entity(mpee));
                    } /*else {
                        retour.ModuleParECF.Add(mapModParECF.ES2Entity(mpee));
                    }*/
                }
            }

            List<ModuleParECFES> lstModulesARetirer = new List<ModuleParECFES>();
            foreach(ModuleParECFES mpee in es.ListeModuleParECF) {
                ModuleES me = new ModuleES();
                me.IdModule = mpee.IdModule;
                if(!es.ListeModule.Contains(me)) {
                    lstModulesARetirer.Add(mpee);
                }
            }

            foreach(ModuleParECFES mpee in lstModulesARetirer) {
                es.ListeModuleParECF.Remove(mpee);
                ModuleParECFOPManager.SupprimerModuleParECF(ModuleParECFOPManager.GetModuleParECFByIdModuleIdECF(mpee.IdModule, mpee.IdECF));
                // retour.ModuleParECF.Remove(mpe);
            }


            if(alreadyAttached) {
                EntityConnection.GetContext().ECF.ApplyCurrentValues(retour);
            }
            return retour;
        }
    }
}
